package com.supermarket.manage.provider.outstock.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.supermarket.manage.common.constant.StockConstant;
import com.supermarket.manage.common.dto.PageBean;
import com.supermarket.manage.common.dto.home.request.HomeInitParams;
import com.supermarket.manage.common.dto.home.response.ProfitDataDto;
import com.supermarket.manage.common.dto.home.response.TopDto;
import com.supermarket.manage.common.dto.home.response.TrendDto;
import com.supermarket.manage.common.dto.prod.response.ProductDto;
import com.supermarket.manage.common.dto.stock.request.OutstockPageParams;
import com.supermarket.manage.common.dto.stock.response.OutProdDto;
import com.supermarket.manage.common.dto.stock.response.OutstockDto;
import com.supermarket.manage.common.pojo.Outstock;
import com.supermarket.manage.common.pojo.OutstockProd;
import com.supermarket.manage.common.pojo.Product;
import com.supermarket.manage.common.utils.BigDecimalUtil;
import com.supermarket.manage.common.utils.TimeUtil;
import com.supermarket.manage.provider.api.outstock.OutstockService;
import com.supermarket.manage.provider.api.product.ProductService;
import com.supermarket.manage.provider.outstock.mapper.OutstockMapper;
import com.supermarket.manage.provider.outstock.mapper.OutstockProdMapper;
import com.supermarket.manage.provider.util.IDUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Faxon
 * @version 1.0
 * @date 2020-03-16 19:29
 **/
@Service(version = "1.0.0")
public class OutstockServiceImpl implements OutstockService {

    @Resource
    private OutstockMapper outstockMapper;

    @Resource
    private OutstockProdMapper outstockProdMapper;

    @Resource
    private IDUtil idUtil;

    @Reference(version = "1.0.0")
    private ProductService productService;

    @Override
    public PageBean<Outstock> getOutstockPageList(OutstockPageParams params) {
        PageHelper.startPage(params.getPage(), params.getSize());
        Page<Outstock> page = outstockMapper.getInstockPageList(params);
        if (page == null) {
            return null;
        }
        return new PageBean<>(page.getPageNum(), page.getPageSize(), page.getResult(), page.getTotal());
    }

    @Override
    public OutstockDto getOutstockById(String id) {
        Outstock outstock = outstockMapper.selectById(id);
        if (outstock == null) {
            return null;
        }
        OutstockDto dto = new OutstockDto();
        BeanUtils.copyProperties(outstock, dto);
        //查询入库商品信息
        QueryWrapper<OutstockProd> wrapper = new QueryWrapper<>();
        wrapper.eq("outstock_id", id);
        List<OutstockProd> outstockProds = outstockProdMapper.selectList(wrapper);
        //将查询结果封装到map中
        Map<String, OutProdDto> map = new HashMap<>(outstockProds.size());
        List<String> ids = new ArrayList<>();
        outstockProds.forEach(i -> {
            ids.add(i.getPid());
            OutProdDto outProd = new OutProdDto();
            outProd.setOid(i.getOid());
            outProd.setOutstockId(i.getOutstockId());
            outProd.setPid(i.getPid());
            outProd.setPnumber(i.getPnumber());
            outProd.setSubtotal(i.getSubtotal());
            outProd.setGray(Boolean.FALSE);
            map.put(i.getPid(), outProd);
        });
        //获取商品详情
        List<ProductDto> prods = productService.getProdDtoByPids(ids);
        List<OutProdDto> data = new ArrayList<>();
        prods.forEach(p -> {
            OutProdDto outProd = map.get(p.getPid());
            if (outProd != null) {
                outProd.setPname(p.getPname());
                outProd.setUnitName(p.getUnitName());
                outProd.setPic(p.getPic());
                outProd.setSalePrice(p.getSalePrice());
                outProd.setFirstCname(p.getFirstCname());
                outProd.setSecondCname(p.getSecondCname());
                outProd.setThirdCname(p.getThirdCname());
            }
            data.add(outProd);
        });
        dto.setOutProdDtos(data);
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean doneOutstockById(Outstock outstock) {
        //修改关联商品库存
        QueryWrapper<OutstockProd> wrapper = new QueryWrapper<>();
        wrapper.eq("outstock_id", outstock.getId());
        List<OutstockProd> prodList = outstockProdMapper.selectList(wrapper);
        List<Product> products = new ArrayList<>();
        prodList.forEach(p -> {
            Product product = new Product();
            product.setPid(p.getPid());
            product.setStockNumber(p.getPnumber());
            products.add(product);
        });
        //减少商品库存
        productService.reduceStockingNumber(products);
        //修改出库单状态
        outstock.setUpdated(new Date());
        return outstockMapper.updateById(outstock) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteOutstockById(String id) {
        QueryWrapper<OutstockProd> wrapper = new QueryWrapper<>();
        wrapper.eq("outstock_id", id);
        outstockProdMapper.delete(wrapper);
        outstockMapper.deleteById(id);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOutstock(Outstock outstock) {
        //添加单据
        if (outstock.getType().equals(StockConstant.SALE)) {
            outstock.setId(idUtil.getSaleOutId());
        } else {
            outstock.setId(idUtil.getBackOutId());
        }
        Date date = new Date();
        outstock.setCreated(date);
        outstock.setUpdated(date);
        outstockMapper.insert(outstock);
        //添加关联商品
        List<OutstockProd> outstockProds = outstock.getOutstockProds();
        outstockProds.forEach(p -> {
            p.setOid(idUtil.getUUID());
            p.setOutstockId(outstock.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
        });
        outstockProdMapper.insertList(outstockProds);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateOutstock(Outstock outstock) {
        //更新单据
        outstock.setUpdated(new Date());
        outstockMapper.updateById(outstock);
        //删除原来关联商品
        QueryWrapper<OutstockProd> wrapper = new QueryWrapper<>();
        wrapper.eq("outstock_id", outstock.getId());
        outstockProdMapper.delete(wrapper);
        //添加关联商品
        List<OutstockProd> outstockProds = outstock.getOutstockProds();
        outstockProds.forEach(p -> {
            p.setOid(idUtil.getUUID());
            p.setOutstockId(outstock.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
        });
        outstockProdMapper.insertList(outstockProds);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addOutstockAndUpdateStockingNumber(Outstock outstock) {
        //添加单据
        if (outstock.getType().equals(StockConstant.SALE)) {
            outstock.setId(idUtil.getSaleOutId());
        } else {
            outstock.setId(idUtil.getBackOutId());
        }
        Date date = new Date();
        outstock.setCreated(date);
        outstock.setUpdated(date);
        outstockMapper.insert(outstock);
        //添加关联商品并减少商品库存
        List<OutstockProd> outstockProds = outstock.getOutstockProds();
        List<Product> products = new ArrayList<>();
        outstockProds.forEach(p -> {
            p.setOid(idUtil.getUUID());
            p.setOutstockId(outstock.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
            Product product = new Product();
            product.setPid(p.getPid());
            product.setStockNumber(p.getPnumber());
            products.add(product);
        });
        productService.reduceStockingNumber(products);
        outstockProdMapper.insertList(outstockProds);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateOutstockAndUpdateStockingNumber(Outstock outstock) {
        //更新单据
        outstock.setUpdated(new Date());
        outstockMapper.updateById(outstock);
        //删除原来关联商品
        QueryWrapper<OutstockProd> wrapper = new QueryWrapper<>();
        wrapper.eq("outstock_id", outstock.getId());
        outstockProdMapper.delete(wrapper);
        //添加关联商品并减少商品库存
        List<OutstockProd> outstockProds = outstock.getOutstockProds();
        List<Product> products = new ArrayList<>();
        outstockProds.forEach(p -> {
            p.setOid(idUtil.getUUID());
            p.setOutstockId(outstock.getId());
            p.setPnumber(BigDecimalUtil.formatTwoPoint(p.getPnumber()));
            p.setSubtotal(BigDecimalUtil.formatTwoPoint(p.getSubtotal()));
            Product product = new Product();
            product.setPid(p.getPid());
            product.setStockNumber(p.getPnumber());
            products.add(product);
        });
        productService.reduceStockingNumber(products);
        outstockProdMapper.insertList(outstockProds);
        return Boolean.TRUE;
    }

    @Override
    public ProfitDataDto getSales(HomeInitParams params) {
        List<TopDto<Integer>> sales = outstockMapper.getSales(params);
        ProfitDataDto dataDto = new ProfitDataDto();
        BigDecimal zero = new BigDecimal("0.00");
        dataDto.setSales(zero);
        dataDto.setPurchasesBack(zero);
        if (sales != null && sales.size() > 0) {
            for (TopDto<Integer> sale : sales) {
                if (sale.getObj().equals(StockConstant.SALE)) {
                    dataDto.setSales(BigDecimalUtil.formatTwoPoint(sale.getSum()));
                }
                if (sale.getObj().equals(StockConstant.BACK)) {
                    dataDto.setPurchasesBack(BigDecimalUtil.formatTwoPoint(sale.getSum()));
                }
            }
        }
        return dataDto;
    }

    @Override
    public List<TrendDto> getSalesTrend(HomeInitParams params) {
        List<TrendDto> data = outstockMapper.getSalesTrend(params);
        List<String> everyDate = TimeUtil.getEveryDate(params.getBeginTime(), params.getEndTime());
        if (everyDate == null) {
            return data;
        } else {
            List<TrendDto> result = new ArrayList<>();
            everyDate.forEach(e -> {
                TrendDto dto = new TrendDto();
                dto.setTime(e);
                dto.setSum(BigDecimalUtil.formatTwoPoint(new BigDecimal("0")));
                data.forEach(d -> {
                    if (e.equals(d.getTime())) {
                        dto.setSum(BigDecimalUtil.formatTwoPoint(d.getSum()));
                    }
                });
                result.add(dto);
            });
            return result;
        }
    }

    @Override
    public Outstock getMemberByOutStockId(String id) {
        QueryWrapper<Outstock> wrapper = new QueryWrapper<>();
        wrapper.select("member_id", "actually_price");
        wrapper.eq("id", id);
        return outstockMapper.selectOne(wrapper);
    }

    @Override
    public List<TopDto<String>> getTopMember(HomeInitParams params) {
        return outstockMapper.getTopMember(params);
    }

    @Override
    public List<Outstock> getOutstockList(OutstockPageParams params) {
        return outstockMapper.getOutstockList(params);
    }
}
